﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;

namespace BrainTechLLC.FolderExplorer
{
    public class BreadthFirstSearch
    {
        public FolderViewModel FindChild(FolderViewModel f, Func<FolderViewModel, bool> action, Func<FolderViewModel, bool> lookInDir)
        {
            Dictionary<string, FolderViewModel> folderList = new Dictionary<string, FolderViewModel>();
            return FindChild(f, action, lookInDir, 0, 20, ref folderList);
        }

        public FolderViewModel FindChild(FolderViewModel f, Func<FolderViewModel, bool> action, Func<FolderViewModel, bool> lookInDir, int currentDepth, int maxDepth, Action<Dictionary<string, FolderViewModel>> done, ref Dictionary<string, FolderViewModel> folderList)
        {
            FolderViewModel found = FindChild(f, action, lookInDir, currentDepth, maxDepth, ref folderList);
            if (done != null)
            {
                done(folderList);
            }
            return found;
        }

        public FolderViewModel FindChild(FolderViewModel f, Func<FolderViewModel, bool> action, Func<FolderViewModel, bool> lookInDir, int currentDepth, int maxDepth, ref Dictionary<string, FolderViewModel> folderList)
        {
            if (action(f))
                return f;

            if (!lookInDir(f))
                return null;

            var found = f.FindInImmediateChildren(action, lookInDir, ref folderList);

            if (found != null)
                return found;

            if (currentDepth < maxDepth)
            {
                var folderListNow = new List<FolderViewModel>();

                for (int n = currentDepth; n < maxDepth; n++)
                {
                    folderListNow.Clear();
                    List<string> toRemove = new List<string>();

                    foreach (var kvpFold in folderList)
                    {
                        var fold = kvpFold.Value;

                        if (fold.Depth == n)
                        {
                            folderListNow.Add(fold);
                        }
                        else if (fold.Depth < n)
                        {
                            toRemove.Add(fold.FullPath);
                        }
                    }

                    for (int x = 0; x < toRemove.Count; x++)
                    {
                        folderList.Remove(toRemove[x]);
                    }

                    for (int i = 0; i < folderListNow.Count; i++)
                    {
                        var fold = folderListNow[i];

                        if (action(fold))
                        {
                            return fold;
                        }

                        var foundIt = FindChild(fold, action, lookInDir, n, n, ref folderList); // was n+1

                        if (foundIt != null)
                            return foundIt;
                    }
                }
            }

            return null;
        }
    }
}
